package org.dromara.system.service.impl;

import com.alibaba.nacos.common.utils.IoUtils;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FilenameUtils;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.system.config.MinioConfig;
import org.dromara.system.utils.StrFile;
import org.dromara.system.service.ISysFileService;
import org.dromara.system.utils.FileTypeUtils;
import org.dromara.system.utils.Seq;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * Minio 文件存储
 *
 * @author ruoyi
 */
@Service
@RequiredArgsConstructor
public class MinioSysFileServiceImpl implements ISysFileService {

    private final MinioConfig minioConfig;
    private final MinioClient client;

    /**
     * Minio文件上传接口
     *
     * @param file 上传的文件
     * @return 访问地址
     * @throws Exception
     */
    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        String fileName = extractFilename(file);
        InputStream inputStream = file.getInputStream();
        PutObjectArgs args = PutObjectArgs.builder()
            .bucket(minioConfig.getBucketName())
            .object(fileName)
            .stream(inputStream, file.getSize(), -1)
            .contentType(file.getContentType())
            .build();
        client.putObject(args);
        IoUtils.closeQuietly(inputStream);
        return minioConfig.getDomain() + "/" + minioConfig.getBucketName() + "/" + fileName;
    }


    /**
     * 字符串保存成文件到minio服务器
     * @param strFile 字符串文件
     * @return
     * @throws Exception
     */
    public String uploadStringToMinio(StrFile strFile) throws Exception {
        String fileName = extractFilename(strFile.getFileName());
        try (InputStream inputStream = new ByteArrayInputStream(strFile.getContent().getBytes(StandardCharsets.UTF_8))) {
            PutObjectArgs args = PutObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .stream(inputStream, inputStream.available(), -1)
                .contentType(strFile.getContentType())
                .build();
            client.putObject(args);
        }
        return minioConfig.getDomain() + "/" + minioConfig.getBucketName() + "/" + fileName;
    }

    /**
     * 编码文件名
     */
    public static final String extractFilename(MultipartFile file) {
        return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
            FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), FileTypeUtils.getExtension(file));
    }

    /**
     * 编码文件名
     */
    public static final String extractFilename(String fileName) {
        return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
            FilenameUtils.getBaseName(fileName), Seq.getId(Seq.uploadSeqType), FilenameUtils.getExtension(fileName));
    }
}
